#include "main/utils.h"
using namespace std;

// =========== solution1 ===============
class temp {
  public:
    temp() {
      ++n;
      sum += n;
    }
    static void reset() {
      n = 0;
      sum = 0;
    }
    static int getSum() {
      return sum;
    }
  private:
    static int n;
    static int sum;
};

int temp::n = 0;
int temp::sum = 0;

int solution1(int n) {
  temp::reset();
  temp* a = new temp[n];
  delete []a;
  a = nullptr;
  return temp::getSum();
}

// =========== solution2 ===============
class base {
  public:
    virtual int sum(int n) {
      return 0;
    }
};

class base;
base* Array[2];

class derived: public base {
  public:
    virtual int sum(int n) {
      return Array[!!n]->sum(n - 1) + n;
   }
};

int solution2(int n) {
  base a;
  derived b;
  Array[0] = &a;
  Array[1] = &b;
  return Array[1]->sum(n);
}

// =========== solution3 ===============
typedef int (*fun)(int);

int solution3_teminator(int n) {
  return 0;
}

int solution3(int n) {
  static fun f[2] = {solution3_teminator, solution3};
  return n + f[!!n](n - 1);
}

// =========== solution4 ===============
template <int n>
struct solution4 {
  enum Value {
    N = solution4<n - 1>::N + n
  };
};

template <>
struct solution4<1> {
  enum Value {
    N = 1
  };
};

int main() {
  const int n = 50;
  int sum1 = solution1(n);
  int sum2 = solution2(n);
  int sum3 = solution3(n);
  int sum4 = solution4<n>::N;
  cout << "1+2+...+50 = " << sum1 << " " << sum2 << " " << sum3 << " " << sum4 << endl;

  return 0;
}
